package com.easylinkin.linkappapi.meterbilling.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.meterbilling.entity.ResidentInfo;
import com.easylinkin.linkappapi.meterbilling.mapper.ResidentInfoMapper;
import com.easylinkin.linkappapi.meterbilling.mapper.RoomTenantryInfoMapper;
import com.easylinkin.linkappapi.meterbilling.service.ResidentService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.sm.constant.UserConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import site.morn.exception.ApplicationMessages;
import site.morn.util.MessageDigestUtils;

import javax.annotation.Resource;

import java.util.List;

import static site.morn.constant.DigestConstant.Algorithms.SPRING_B_CRYPT;

/**
 * class info :
 *
 * @author liuqihang
 * @date 2021/7/17 15:26
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class ResidentServiceImpl extends ServiceImpl<ResidentInfoMapper, ResidentInfo> implements ResidentService {

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private CommonService commonService;

    @Resource
    private RoomTenantryInfoMapper roomTenantryInfoMapper;

    @Override
    public String saveResidentInfo(ResidentInfo residentInfo) {
        checkResidentInfoNullAttribute(residentInfo);
        Assert.notNull(residentInfo.getPassword(), "密码不能为空");
        /*boolean b1 = checkRoomTenantryInfoDuplicateAttribute(new ResidentInfo().setName(residentInfo.getName()));
        if(b1){
            return "住户名称重复";
        }*/
        boolean b2 = checkRoomTenantryInfoDuplicateAttribute(new ResidentInfo().setPhone(residentInfo.getPhone()));
        if(b2){
            return "住户手机号重复";
        }
        String encryptPassword = MessageDigestUtils.encrypt(SPRING_B_CRYPT, residentInfo.getPassword());
        log.info("encryptPassword = " + encryptPassword);
        residentInfo.setPassword(encryptPassword);

        LinkappUser current = linkappUserContextProducer.getCurrent();
        commonService.setCreateAndModifyInfo(residentInfo);
        residentInfo.setDeleteStatus(0).setTenantId(current.getTenantId());
        baseMapper.insert(residentInfo);
        return null;
    }

    @Override
    public String updateResidentInfo(ResidentInfo residentInfo) {
        checkResidentInfoNullAttribute(residentInfo);
       /* boolean b1 = checkRoomTenantryInfoDuplicateAttribute(new ResidentInfo().setId(residentInfo.getId()).setName(residentInfo.getName()));
        if(b1){
            return "住户名称已存在";
        }*/
        boolean b2 = checkRoomTenantryInfoDuplicateAttribute(new ResidentInfo().setId(residentInfo.getId()).setPhone(residentInfo.getPhone()));
        if(b2){
            return "住户手机号已存在";
        }
        commonService.setModifyInfo(residentInfo);
        residentInfo.setPassword(null);
        baseMapper.updateById(residentInfo);
        return null;
    }

    @Override
    public ResidentInfo getResidentInfoById(Integer residentId) {
        ResidentInfo residentInfo = baseMapper.selectById(residentId);
        residentInfo.setPassword(null);
        return residentInfo;
    }

    @Override
    public ResidentInfo getResidentInfoByPhone(String phone) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("phone",phone);
        qw.eq("delete_status",0);
        List<ResidentInfo> residentInfoList = baseMapper.selectList(qw);
        if(ObjectUtils.isEmpty(residentInfoList)){
            return null;
        }
        ResidentInfo residentInfo = residentInfoList.get(0);
        return residentInfo;
    }

    @Override
    public String delete(Integer residentId) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("delete_status",0);
        qw.eq("resident_id",residentId);
        List list = roomTenantryInfoMapper.selectList(qw);
        if(list != null && list.size() > 0){
            return "该住户已绑定房屋合同";
        }
        baseMapper.updateById(new ResidentInfo().setDeleteStatus(1).setId(residentId));
        return null;
    }

    @Override
    public IPage<ResidentInfo> getResidentInfoPage(Page page, ResidentInfo residentInfo) {
        LinkappUser current = linkappUserContextProducer.getNotNullCurrent();

        QueryWrapper qw = new QueryWrapper();
        qw.eq("tenant_id", current.getTenantId());
        if(residentInfo.getName() != null && !"".equals(residentInfo.getName())){
            qw.like("name", residentInfo.getName());
        }
        if(residentInfo.getPhone() != null && !"".equals(residentInfo.getPhone())){
            qw.like("phone", residentInfo.getPhone());
        }
        qw.eq("delete_status",0);
        qw.orderByDesc("create_time");
        IPage<ResidentInfo> residentInfoIPage = baseMapper.selectPage(page, qw);
        List<ResidentInfo> records = residentInfoIPage.getRecords();
        records.forEach(e->{
            e.setPassword(null);
        });
        residentInfoIPage.setRecords(records);
        return residentInfoIPage;
    }

    @Override
    public List<ResidentInfo> getResidentInfoList(ResidentInfo residentInfo) {
        LinkappUser current = linkappUserContextProducer.getNotNullCurrent();

        QueryWrapper qw = new QueryWrapper();
        qw.eq("tenant_id", current.getTenantId());
        if(residentInfo.getName() != null && !"".equals(residentInfo.getName())){
            qw.like("name", residentInfo.getName());
        }
        if(residentInfo.getPhone() != null && !"".equals(residentInfo.getPhone())){
            qw.like("phone", residentInfo.getPhone());
        }
        qw.eq("delete_status",0);
        qw.orderByDesc("create_time");
        List<ResidentInfo> list = baseMapper.selectList(qw);
        list.forEach(e->{
            e.setPassword(null);
        });
        return list;
    }

    @Override
    public void updatePwd(ResidentInfo residentInfo) {
        ResidentInfo oldResidentInfo = null;
        if(StringUtils.isEmpty(residentInfo.getId())){
            QueryWrapper qw = new QueryWrapper();
            qw.eq("phone",residentInfo.getPhone());
            qw.eq("delete_status",0);
            List<ResidentInfo> residentInfoList = baseMapper.selectList(qw);
            if(ObjectUtils.isEmpty(residentInfoList)){
                return ;
            }
            oldResidentInfo = residentInfoList.get(0);
        } else {
            oldResidentInfo = baseMapper.selectById(residentInfo.getId());
        }

        if (MessageDigestUtils.matches(SPRING_B_CRYPT, residentInfo.getPassword(), oldResidentInfo.getPassword())) {
            throw ApplicationMessages.translateException(UserConstant.Error.SECRET_REPEAT);
        }

        String encryptPassword = MessageDigestUtils.encrypt(SPRING_B_CRYPT, residentInfo.getPassword());
        log.info("encryptPassword = " + encryptPassword);
        residentInfo.setPassword(encryptPassword);
        residentInfo.setId(oldResidentInfo.getId());
        commonService.setModifyInfo(residentInfo);
        residentInfo.setName(null).setPhone(null);
        baseMapper.updateById(residentInfo);
    }

    /**
     * 验证住户重复值
     * @param residentInfo
     * @return  true:重复，false:正常
     */
    private boolean checkRoomTenantryInfoDuplicateAttribute(ResidentInfo residentInfo){
        QueryWrapper qw = new QueryWrapper();
        qw.eq("delete_status", 0);
        if(residentInfo.getName() != null){
            qw.eq("name", residentInfo.getName());
        }
        if(residentInfo.getPhone() != null){
            qw.eq("phone", residentInfo.getPhone());
        }
        if(residentInfo.getId() != null){
            qw.notIn("id", residentInfo.getId());
        }
        Integer count = baseMapper.selectCount(qw);
        if(count != null && count > 0){
            return true;
        }
        return false;
    }

    public void checkResidentInfoNullAttribute(ResidentInfo residentInfo){
        Assert.notNull(residentInfo.getName(), "住户姓名不能为空");
        Assert.notNull(residentInfo.getPhone(), "手机号码不能为空");

    }

    @Override
    public ResidentInfo getResidentInfoByPhoneApp(ResidentInfo residentInfo){
        String phone = linkappUserContextProducer.getCurrentUsername();
        ResidentInfo oldResidentInfo = null;
        if(residentInfo == null || StringUtils.isEmpty(residentInfo.getId())){
            QueryWrapper qw = new QueryWrapper();
            qw.eq("phone",phone);
            qw.eq("delete_status",0);
            List<ResidentInfo> residentInfoList = baseMapper.selectList(qw);
            if(ObjectUtils.isEmpty(residentInfoList)){
                return oldResidentInfo;
            }
            oldResidentInfo = residentInfoList.get(0);
        } else {
            oldResidentInfo = baseMapper.selectById(residentInfo.getId());
        }
        if(oldResidentInfo == null){
            return  oldResidentInfo;
        }
        oldResidentInfo.setPassword(null);
        return oldResidentInfo;
    }
}
